Building a Convolutional Neural Network

This notebook is a brief guide to using TensorFlow's layers modules to build a convolutional neural network model to recognize the handwritten digits in the MNIST data set, which contains 60,000 training examples and 10,000 test examples of the handwritten digits 0–9, stored as 28x28-pixel black-and-white images.

The layers module provides methods that facilitate the creation of convolutional neural networks with fully connected layers and convolutional layers, adding activation functions, and applying dropout regularization.

Convolutional neural networks (CNNs) are an architecture for image classification tasks consisting of a series of filters that are applied to images represented as pixel vectors to extract (and learn) higher-level features, which can later be used for classification.

A CNN contains three components:

  • Convolutional layers, each of which applies a specified convolution filter to the image. Each layer encodes subregions of the image as a single value to be stored in the output feature map.
    • Pooling layers, which reduce the dimensionality of the feature map by using non-linear functions (e.g., max-pooling, average-pooling, etc.). Max pooling partitions the input image into a set of non-overlapping rectangles (e.g., 2x2-pixel regions) and, for each such rectangle, outputs the maximum, thus reducing the spatial size of the representation and hence the amount of computation needed in the network. This also helps control overfitting. Pooling layers are commonly inserted between successive convolutional layers.
    • Fully-connected layers (where every node in the layer is connected to every node in the preceding layer), which perform classification on the features extracted by the convolutional layers.

Each CNN is composed of a stack of modules where each module consists of a convolutional layer followed by a pooling layer, together performing feature extraction. The last convolutional module is linked to one or more fully-connected (i.e., dense) layers that perform classification. The last dense layer in a CNN contains a single node for each of the possible classes the model may predict, with a softmax activation function to generate a value between 0–1 for each node. The softmax values for a given image are interpreted as a measure of how likely it is that the image belongs to each of the possible classes. (The sum of all the softmax values is equal to 1.)

Let's start by importing the necessary modules.


In [9]:
!pip install --upgrade tensorflow


Requirement already up-to-date: tensorflow in ./common/.virtualenv/python2/lib/python2.7/site-packages
Requirement already up-to-date: numpy>=1.11.0 in ./common/.virtualenv/python2/lib/python2.7/site-packages (from tensorflow)
Requirement already up-to-date: six>=1.10.0 in ./common/.virtualenv/python2/lib/python2.7/site-packages (from tensorflow)
Requirement already up-to-date: mock>=2.0.0 in ./common/.virtualenv/python2/lib/python2.7/site-packages (from tensorflow)
Requirement already up-to-date: wheel in ./common/.virtualenv/python2/lib/python2.7/site-packages (from tensorflow)
Requirement already up-to-date: protobuf>=3.1.0 in ./common/.virtualenv/python2/lib/python2.7/site-packages (from tensorflow)
Requirement already up-to-date: funcsigs>=1; python_version < "3.3" in /usr/local/lib/python2.7/dist-packages (from mock>=2.0.0->tensorflow)
Requirement already up-to-date: pbr>=0.11 in ./common/.virtualenv/python2/lib/python2.7/site-packages (from mock>=2.0.0->tensorflow)
Requirement already up-to-date: setuptools in ./common/.virtualenv/python2/lib/python2.7/site-packages (from protobuf>=3.1.0->tensorflow)
Requirement already up-to-date: packaging>=16.8 in ./common/.virtualenv/python2/lib/python2.7/site-packages (from setuptools->protobuf>=3.1.0->tensorflow)
Requirement already up-to-date: appdirs>=1.4.0 in ./common/.virtualenv/python2/lib/python2.7/site-packages (from setuptools->protobuf>=3.1.0->tensorflow)
Requirement already up-to-date: pyparsing in ./common/.virtualenv/python2/lib/python2.7/site-packages (from packaging>=16.8->setuptools->protobuf>=3.1.0->tensorflow)

In [2]:
import tensorflow as tf

# Import MNIST data
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/tmp/data/", one_hot=True)


Extracting /tmp/data/train-images-idx3-ubyte.gz
Extracting /tmp/data/train-labels-idx1-ubyte.gz
Extracting /tmp/data/t10k-images-idx3-ubyte.gz
Extracting /tmp/data/t10k-labels-idx1-ubyte.gz

In [3]:
# Parameters
learning_rate = 0.001
training_iters = 200000
batch_size = 128
display_step = 10

# Network Parameters
n_input = 784 # MNIST data input (img shape: 28*28)
n_classes = 10 # MNIST total classes (0-9 digits)
dropout = 0.75 # Dropout, probability to keep units

# tf Graph input
x = tf.placeholder(tf.float32, [None, n_input])
y = tf.placeholder(tf.float32, [None, n_classes])
keep_prob = tf.placeholder(tf.float32) #dropout (keep probability)

In [4]:
# Create some wrappers for simplicity
def conv2d(x, W, b, strides=1):
    # Conv2D wrapper, with bias and relu activation
    x = tf.nn.conv2d(x, W, strides=[1, strides, strides, 1], padding='SAME')
    x = tf.nn.bias_add(x, b)
    return tf.nn.relu(x)


def maxpool2d(x, k=2):
    # MaxPool2D wrapper
    return tf.nn.max_pool(x, ksize=[1, k, k, 1], strides=[1, k, k, 1],
                          padding='SAME')


# Create model
def conv_net(x, weights, biases, dropout):
    # Reshape input picture
    x = tf.reshape(x, shape=[-1, 28, 28, 1])

    # Convolution Layer
    conv1 = conv2d(x, weights['wc1'], biases['bc1'])
    # Max Pooling (down-sampling)
    conv1 = maxpool2d(conv1, k=2)

    # Convolution Layer
    conv2 = conv2d(conv1, weights['wc2'], biases['bc2'])
    # Max Pooling (down-sampling)
    conv2 = maxpool2d(conv2, k=2)

    # Fully connected layer
    # Reshape conv2 output to fit fully connected layer input
    fc1 = tf.reshape(conv2, [-1, weights['wd1'].get_shape().as_list()[0]])
    fc1 = tf.add(tf.matmul(fc1, weights['wd1']), biases['bd1'])
    fc1 = tf.nn.relu(fc1)
    # Apply Dropout
    fc1 = tf.nn.dropout(fc1, dropout)

    # Output, class prediction
    out = tf.add(tf.matmul(fc1, weights['out']), biases['out'])
    return out

In [7]:
# Store layers weight & bias
weights = {
    # 5x5 conv, 1 input, 32 outputs
    'wc1': tf.Variable(tf.random_normal([5, 5, 1, 32])),
    # 5x5 conv, 32 inputs, 64 outputs
    'wc2': tf.Variable(tf.random_normal([5, 5, 32, 64])),
    # fully connected, 7*7*64 inputs, 1024 outputs
    'wd1': tf.Variable(tf.random_normal([7*7*64, 1024])),
    # 1024 inputs, 10 outputs (class prediction)
    'out': tf.Variable(tf.random_normal([1024, n_classes]))
}

biases = {
    'bc1': tf.Variable(tf.random_normal([32])),
    'bc2': tf.Variable(tf.random_normal([64])),
    'bd1': tf.Variable(tf.random_normal([1024])),
    'out': tf.Variable(tf.random_normal([n_classes]))
}

# Construct model
pred = conv_net(x, weights, biases, keep_prob)

# Define loss and optimizer
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)

# Evaluate model
correct_pred = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))

# Initializing the variables
init = tf.global_variables_initializer()

In [6]:
# Launch the graph
with tf.Session() as sess:
    sess.run(init)
    step = 1
    # Keep training until reach max iterations
    while step * batch_size < training_iters:
        batch_x, batch_y = mnist.train.next_batch(batch_size)
        # Run optimization op (backprop)
        sess.run(optimizer, feed_dict={x: batch_x, y: batch_y,
                                       keep_prob: dropout})
        if step % display_step == 0:
            # Calculate batch loss and accuracy
            loss, acc = sess.run([cost, accuracy], feed_dict={x: batch_x,
                                                              y: batch_y,
                                                              keep_prob: 1.})
            print "Iter " + str(step*batch_size) + ", Minibatch Loss= " + \
                  "{:.6f}".format(loss) + ", Training Accuracy= " + \
                  "{:.5f}".format(acc)
        step += 1
    print "Optimization Finished!"

    # Calculate accuracy for 256 mnist test images
    print "Testing Accuracy:", \
        sess.run(accuracy, feed_dict={x: mnist.test.images[:256],
                                      y: mnist.test.labels[:256],
                                      keep_prob: 1.})


Iter 1280, Minibatch Loss= 27240.914062, Training Accuracy= 0.22656
Iter 2560, Minibatch Loss= 8924.638672, Training Accuracy= 0.50781
Iter 3840, Minibatch Loss= 6502.008789, Training Accuracy= 0.67969
Iter 5120, Minibatch Loss= 4761.916016, Training Accuracy= 0.79688
Iter 6400, Minibatch Loss= 2325.581055, Training Accuracy= 0.84375
Iter 7680, Minibatch Loss= 6392.742188, Training Accuracy= 0.79688
Iter 8960, Minibatch Loss= 2281.822266, Training Accuracy= 0.85156
Iter 10240, Minibatch Loss= 3390.894043, Training Accuracy= 0.82031
Iter 11520, Minibatch Loss= 1095.840332, Training Accuracy= 0.94531
Iter 12800, Minibatch Loss= 2503.158936, Training Accuracy= 0.85156
Iter 14080, Minibatch Loss= 1134.362793, Training Accuracy= 0.90625
Iter 15360, Minibatch Loss= 1577.371094, Training Accuracy= 0.92188
Iter 16640, Minibatch Loss= 2199.084961, Training Accuracy= 0.90625
Iter 17920, Minibatch Loss= 1698.583984, Training Accuracy= 0.87500
Iter 19200, Minibatch Loss= 1015.906067, Training Accuracy= 0.93750
Iter 20480, Minibatch Loss= 528.396851, Training Accuracy= 0.94531
Iter 21760, Minibatch Loss= 2913.404541, Training Accuracy= 0.85156
Iter 23040, Minibatch Loss= 889.879089, Training Accuracy= 0.95312
Iter 24320, Minibatch Loss= 1186.059448, Training Accuracy= 0.92969
Iter 25600, Minibatch Loss= 1485.508789, Training Accuracy= 0.88281
Iter 26880, Minibatch Loss= 938.826416, Training Accuracy= 0.94531
Iter 28160, Minibatch Loss= 875.896240, Training Accuracy= 0.92969
Iter 29440, Minibatch Loss= 868.406250, Training Accuracy= 0.92188
Iter 30720, Minibatch Loss= 838.553101, Training Accuracy= 0.93750
Iter 32000, Minibatch Loss= 819.531067, Training Accuracy= 0.94531
Iter 33280, Minibatch Loss= 1304.348267, Training Accuracy= 0.88281
Iter 34560, Minibatch Loss= 547.503296, Training Accuracy= 0.96875
Iter 35840, Minibatch Loss= 264.640900, Training Accuracy= 0.97656
Iter 37120, Minibatch Loss= 947.314026, Training Accuracy= 0.92188
Iter 38400, Minibatch Loss= 182.436340, Training Accuracy= 0.97656
Iter 39680, Minibatch Loss= 272.362305, Training Accuracy= 0.96875
Iter 40960, Minibatch Loss= 1343.914551, Training Accuracy= 0.90625
Iter 42240, Minibatch Loss= 679.182312, Training Accuracy= 0.94531
Iter 43520, Minibatch Loss= 455.874695, Training Accuracy= 0.96875
Iter 44800, Minibatch Loss= 181.285156, Training Accuracy= 0.97656
Iter 46080, Minibatch Loss= 118.447289, Training Accuracy= 0.99219
Iter 47360, Minibatch Loss= 1715.387695, Training Accuracy= 0.91406
Iter 48640, Minibatch Loss= 1031.726562, Training Accuracy= 0.92969
Iter 49920, Minibatch Loss= 930.794495, Training Accuracy= 0.92188
Iter 51200, Minibatch Loss= 396.990173, Training Accuracy= 0.95312
Iter 52480, Minibatch Loss= 173.889450, Training Accuracy= 0.97656
Iter 53760, Minibatch Loss= 239.445343, Training Accuracy= 0.96875
Iter 55040, Minibatch Loss= 374.163635, Training Accuracy= 0.96094
Iter 56320, Minibatch Loss= 216.164307, Training Accuracy= 0.96094
Iter 57600, Minibatch Loss= 599.852112, Training Accuracy= 0.96875
Iter 58880, Minibatch Loss= 692.060181, Training Accuracy= 0.96094
Iter 60160, Minibatch Loss= 434.429138, Training Accuracy= 0.96875
Iter 61440, Minibatch Loss= 244.761230, Training Accuracy= 0.96094
Iter 62720, Minibatch Loss= 526.000000, Training Accuracy= 0.95312
Iter 64000, Minibatch Loss= 806.598267, Training Accuracy= 0.96875
Iter 65280, Minibatch Loss= 743.341919, Training Accuracy= 0.93750
Iter 66560, Minibatch Loss= 666.270508, Training Accuracy= 0.96094
Iter 67840, Minibatch Loss= 599.168945, Training Accuracy= 0.96875
Iter 69120, Minibatch Loss= 532.359741, Training Accuracy= 0.96094
Iter 70400, Minibatch Loss= 645.349060, Training Accuracy= 0.98438
Iter 71680, Minibatch Loss= 665.532532, Training Accuracy= 0.92969
Iter 72960, Minibatch Loss= 456.968597, Training Accuracy= 0.96094
Iter 74240, Minibatch Loss= 547.131348, Training Accuracy= 0.94531
Iter 75520, Minibatch Loss= 467.321289, Training Accuracy= 0.96094
Iter 76800, Minibatch Loss= 77.974533, Training Accuracy= 0.98438
Iter 78080, Minibatch Loss= 201.818390, Training Accuracy= 0.97656
Iter 79360, Minibatch Loss= 628.367798, Training Accuracy= 0.92188
Iter 80640, Minibatch Loss= 287.636353, Training Accuracy= 0.97656
Iter 81920, Minibatch Loss= 483.605804, Training Accuracy= 0.95312
Iter 83200, Minibatch Loss= 156.676498, Training Accuracy= 0.96875
Iter 84480, Minibatch Loss= 456.972229, Training Accuracy= 0.94531
Iter 85760, Minibatch Loss= 389.791382, Training Accuracy= 0.96875
Iter 87040, Minibatch Loss= 227.378143, Training Accuracy= 0.96094
Iter 88320, Minibatch Loss= 595.285522, Training Accuracy= 0.95312
Iter 89600, Minibatch Loss= 191.082657, Training Accuracy= 0.96875
Iter 90880, Minibatch Loss= 238.573456, Training Accuracy= 0.96094
Iter 92160, Minibatch Loss= 397.825653, Training Accuracy= 0.96875
Iter 93440, Minibatch Loss= 443.401703, Training Accuracy= 0.96094
Iter 94720, Minibatch Loss= 962.649353, Training Accuracy= 0.92969
Iter 96000, Minibatch Loss= 246.745224, Training Accuracy= 0.96094
Iter 97280, Minibatch Loss= 200.676422, Training Accuracy= 0.97656
Iter 98560, Minibatch Loss= 106.868500, Training Accuracy= 0.97656
Iter 99840, Minibatch Loss= 479.897156, Training Accuracy= 0.94531
Iter 101120, Minibatch Loss= 610.474976, Training Accuracy= 0.96094
Iter 102400, Minibatch Loss= 466.124756, Training Accuracy= 0.96094
Iter 103680, Minibatch Loss= 266.598389, Training Accuracy= 0.96094
Iter 104960, Minibatch Loss= 573.704041, Training Accuracy= 0.94531
Iter 106240, Minibatch Loss= 530.040771, Training Accuracy= 0.95312
Iter 107520, Minibatch Loss= 780.795959, Training Accuracy= 0.96094
Iter 108800, Minibatch Loss= 294.341492, Training Accuracy= 0.96875
Iter 110080, Minibatch Loss= 312.829407, Training Accuracy= 0.97656
Iter 111360, Minibatch Loss= 39.268074, Training Accuracy= 0.97656
Iter 112640, Minibatch Loss= 334.863953, Training Accuracy= 0.97656
Iter 113920, Minibatch Loss= 285.109680, Training Accuracy= 0.95312
Iter 115200, Minibatch Loss= 250.684265, Training Accuracy= 0.96875
Iter 116480, Minibatch Loss= 203.697189, Training Accuracy= 0.98438
Iter 117760, Minibatch Loss= 174.807434, Training Accuracy= 0.96875
Iter 119040, Minibatch Loss= 132.310791, Training Accuracy= 0.97656
Iter 120320, Minibatch Loss= 181.913010, Training Accuracy= 0.97656
Iter 121600, Minibatch Loss= 261.777100, Training Accuracy= 0.96875
Iter 122880, Minibatch Loss= 298.802582, Training Accuracy= 0.95312
Iter 124160, Minibatch Loss= 196.506683, Training Accuracy= 0.96875
Iter 125440, Minibatch Loss= 175.747955, Training Accuracy= 0.96094
Iter 126720, Minibatch Loss= 88.526886, Training Accuracy= 0.98438
Iter 128000, Minibatch Loss= 5.285034, Training Accuracy= 0.99219
Iter 129280, Minibatch Loss= 287.197571, Training Accuracy= 0.97656
Iter 130560, Minibatch Loss= 392.628845, Training Accuracy= 0.95312
Iter 131840, Minibatch Loss= 0.000000, Training Accuracy= 1.00000
Iter 133120, Minibatch Loss= 107.179260, Training Accuracy= 0.97656
Iter 134400, Minibatch Loss= 328.526917, Training Accuracy= 0.96875
Iter 135680, Minibatch Loss= 347.020538, Training Accuracy= 0.96094
Iter 136960, Minibatch Loss= 441.087341, Training Accuracy= 0.96875
Iter 138240, Minibatch Loss= 574.202271, Training Accuracy= 0.96094
Iter 139520, Minibatch Loss= 65.462334, Training Accuracy= 0.98438
Iter 140800, Minibatch Loss= 519.534546, Training Accuracy= 0.95312
Iter 142080, Minibatch Loss= 234.846436, Training Accuracy= 0.95312
Iter 143360, Minibatch Loss= 167.576202, Training Accuracy= 0.97656
Iter 144640, Minibatch Loss= 53.000839, Training Accuracy= 0.98438
Iter 145920, Minibatch Loss= 0.000000, Training Accuracy= 1.00000
Iter 147200, Minibatch Loss= 304.554321, Training Accuracy= 0.96094
Iter 148480, Minibatch Loss= 493.224976, Training Accuracy= 0.96094
Iter 149760, Minibatch Loss= 198.737259, Training Accuracy= 0.96094
Iter 151040, Minibatch Loss= 56.344398, Training Accuracy= 0.97656
Iter 152320, Minibatch Loss= 119.058678, Training Accuracy= 0.97656
Iter 153600, Minibatch Loss= 268.412781, Training Accuracy= 0.96094
Iter 154880, Minibatch Loss= 76.665466, Training Accuracy= 0.96875
Iter 156160, Minibatch Loss= 826.409668, Training Accuracy= 0.97656
Iter 157440, Minibatch Loss= 146.292953, Training Accuracy= 0.98438
Iter 158720, Minibatch Loss= 222.611481, Training Accuracy= 0.97656
Iter 160000, Minibatch Loss= 0.000000, Training Accuracy= 1.00000
Iter 161280, Minibatch Loss= 96.144951, Training Accuracy= 0.96094
Iter 162560, Minibatch Loss= 162.870575, Training Accuracy= 0.95312
Iter 163840, Minibatch Loss= 13.213531, Training Accuracy= 0.99219
Iter 165120, Minibatch Loss= 247.602829, Training Accuracy= 0.96094
Iter 166400, Minibatch Loss= 293.125946, Training Accuracy= 0.97656
Iter 167680, Minibatch Loss= 178.860153, Training Accuracy= 0.96875
Iter 168960, Minibatch Loss= 32.426491, Training Accuracy= 0.97656
Iter 170240, Minibatch Loss= 44.816460, Training Accuracy= 0.99219
Iter 171520, Minibatch Loss= 135.597610, Training Accuracy= 0.97656
Iter 172800, Minibatch Loss= 277.741913, Training Accuracy= 0.96094
Iter 174080, Minibatch Loss= 124.626442, Training Accuracy= 0.97656
Iter 175360, Minibatch Loss= 271.452148, Training Accuracy= 0.95312
Iter 176640, Minibatch Loss= 44.395477, Training Accuracy= 0.98438
Iter 177920, Minibatch Loss= 116.832573, Training Accuracy= 0.96875
Iter 179200, Minibatch Loss= 198.814941, Training Accuracy= 0.95312
Iter 180480, Minibatch Loss= 114.932838, Training Accuracy= 0.97656
Iter 181760, Minibatch Loss= 83.095085, Training Accuracy= 0.98438
Iter 183040, Minibatch Loss= 110.999619, Training Accuracy= 0.99219
Iter 184320, Minibatch Loss= 31.179642, Training Accuracy= 0.97656
Iter 185600, Minibatch Loss= 0.000000, Training Accuracy= 1.00000
Iter 186880, Minibatch Loss= 91.613594, Training Accuracy= 0.98438
Iter 188160, Minibatch Loss= 32.204247, Training Accuracy= 0.98438
Iter 189440, Minibatch Loss= 31.748756, Training Accuracy= 0.97656
Iter 190720, Minibatch Loss= 202.634186, Training Accuracy= 0.96875
Iter 192000, Minibatch Loss= 48.674606, Training Accuracy= 0.99219
Iter 193280, Minibatch Loss= 334.894714, Training Accuracy= 0.98438
Iter 194560, Minibatch Loss= 10.833282, Training Accuracy= 0.99219
Iter 195840, Minibatch Loss= 390.287842, Training Accuracy= 0.94531
Iter 197120, Minibatch Loss= 37.617661, Training Accuracy= 0.99219
Iter 198400, Minibatch Loss= 189.466751, Training Accuracy= 0.96094
Iter 199680, Minibatch Loss= 69.758118, Training Accuracy= 0.98438
Optimization Finished!
Testing Accuracy: 0.96875